package com.cch.cooperation.api.vip.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cch.cooperation.api.auth.dto.VipRenewDTO;
import com.cch.cooperation.api.auth.service.UserServiceImpl;
import com.cch.cooperation.api.vip.dto.VipAdViewAddRespDTO;
import com.cch.cooperation.api.vip.dto.VipAdViewRemainingDTO;
import com.cch.cooperation.biz.common.lock.Locker;
import com.cch.cooperation.common.util.SnowflakeIdUtil;
import com.cch.cooperation.dao.auth.model.User;
import com.cch.cooperation.dao.vip.mapper.VipAdViewMapper;
import com.cch.cooperation.dao.vip.model.VipAdView;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class VipAdViewServiceImpl {

    @Resource
    public VipAdViewMapper mapper;
    @Resource
    public UserServiceImpl userService;

    private static final Integer VIP_TODAY_GET_AD_COUNT = 2;
    private static final Integer VIP_TOMORROW_GET_AD_COUNT = 5;
    private static final Integer VIP_AD_VIEW_EXPIRE_TIME = 60 * 60 * 24;

    @Locker(key = "'LOCK:VIP_AD_VIEW:ADD' + #userId")
    @Transactional(rollbackFor = Exception.class)
    public VipAdViewAddRespDTO add(String userId) {
        // 查询获取vip剩余观看次数
        VipAdViewRemainingDTO remainingCount = remainingCountForVip(userId);
        boolean isGetVip = remainingCount.getTodayRemainingForVip() == 1 || remainingCount.getTomorrowRemainingForVip() == 1;
        // 添加
        VipAdView vipAdView = new VipAdView();
        vipAdView.setId(SnowflakeIdUtil.getIdStr());
        vipAdView.setUserId(userId);
        vipAdView.setCreateTime(new Date());
        mapper.insert(vipAdView);
        // 会员续期
        if (isGetVip) {
            VipRenewDTO renewReq = new VipRenewDTO();
            renewReq.setUserId(userId);
            renewReq.setSecond(VIP_AD_VIEW_EXPIRE_TIME);
            userService.renewVip(renewReq);
        }
        // 获取会员过期时间
        User user = userService.getById(userId);
        // 获取会员观看信息
        VipAdViewRemainingDTO vipAdViewRemaining = remainingCountForVip(userId);
        return new VipAdViewAddRespDTO(isGetVip, user.getVipExpireTime(), vipAdViewRemaining);
    }

    public VipAdViewRemainingDTO remainingCountForVip(String userId) {
        int todayRemainingCount = 0;
        long today = DateUtil.beginOfDay(new Date()).getTime();
        LambdaQueryWrapper<VipAdView> query = new LambdaQueryWrapper<>();
        query.eq(VipAdView::getUserId, userId);
        query.ge(VipAdView::getCreateTime, DateUtil.beginOfDay(new Date()));
        int viewCount = mapper.selectCount(query);
        User user = userService.getById(userId);
        if (Objects.isNull(user.getVipExpireTime()) || user.getVipExpireTime().getTime() < today) {
            todayRemainingCount = Math.max(VIP_TODAY_GET_AD_COUNT - viewCount, 0);
        }
        int tomorrowRemainingCount = 0;
        long tomorrow = DateUtil.beginOfDay(new Date()).getTime() + TimeUnit.DAYS.toMillis(1);
        if (Objects.isNull(user.getVipExpireTime()) || user.getVipExpireTime().getTime() < tomorrow) {
            tomorrowRemainingCount = Math.max(VIP_TOMORROW_GET_AD_COUNT - viewCount, 0);
        }
        return new VipAdViewRemainingDTO(todayRemainingCount, tomorrowRemainingCount, VIP_TODAY_GET_AD_COUNT, VIP_TOMORROW_GET_AD_COUNT);
    }

}
